<?php
//require_once("core/Frodo.lib.php");

Frodo::import("com.frodo.session.Session");
Frodo::import("com.frodo.core.Document");
Frodo::import("com.frodo.core.ElenentHasNoName");
Frodo::import("com.frodo.utils.StringUtil");
Frodo::import("com.frodo.components.FButton");
Frodo::import("com.frodo.components.FCanvas");

class Application{
	
	private $_session;
	/**
	 * Enter description here...
	 *
	 * @var Document
	 */
	private $_document;
	
	private $_internalCode;
	public function setInternalCode($value){
		$this->_internalCode = $value;
	}
	public function getInternalCode(){
		return $this->_internalCode;
	}
	
	private $_name="";
	public function setName($value){
		$this->_name=$value;
	}
	public function getName(){
		return $this->_name;
	}
	
	private $_path="";
	public function setPath($path){$this->_path=$path;}
	
	public function __construct(){
		$this->_session = Session::getInstance();
		echo "creating application\n<br />";
		//$this->_document = new Document();
	}
	
	public $expired=false;
	
	private function _createChildren(){
		$items=$this->_document->getFrodoElements();
		//echo "sdfsd";
		while($item=$items->item(0)){
			$class = "F".ucfirst(strtolower($item->localName));
			if(!$name=$item->getAttribute("name")){
				throw new ElenentHasNoName();
			}
			if(!isset($this->$name)){
				$this->$name = new $class($item);
				$this->$name->setName($name);
			}
			//var_dump($this->$name);
			$this->$name->setDocument($this->_document);
			//$child=$this->$name->getElementXml($xml,$item);
			$child=$this->$name->asNode();
			$item->parentNode->replaceChild($child,$item);
			//exit();
		}
	}
	
	private function _createDocument(){
		$this->_document = new Document(StringUtil::stringPhpPart(file_get_contents($this->_path)));
		$this->_document->addHeadElement($this->_document->createScript("./js/frodo.js"));
		$form=$this->_document->createForm(Document::$SENDER_FORM_ID,"","post");
		$form->appendChild($this->_document->createInput("__INTERNALCODE_","hidden","__INTERNALCODE_",$this->_internalCode));
		$form->appendChild($this->_document->createInput("___send_element","hidden","___send_element",""));
		$form->appendChild($this->_document->createInput("___event_type","hidden","___event_type",""));
		while($tag=$this->_document->getBody()->getElementsByTagName("*")->item(0)){
			$form->appendChild($tag);
		}
		$this->_document->addBodyElement($form);
	}
	
	public function create(){
		$this->_createDocument();
		$this->_createChildren();
	}
	
	public function getHtml(){
		return $this->_document->asString();
	}
	
	public function dispatchEvents(){
		if (isset($_POST['___event_type'])&&isset($_POST['___send_element'])) {
			$type = $_POST['___event_type'];
			$target= $_POST['___send_element'];
			if(isset($this->$target)){
				$this->$target->dispatchEvent(new Event($type));
			}
		}
	}
	
	public function __destruct(){
		if(get_class($this)==$this->_name&&$this->expired==false){
			Session::getInstance()->__frodoSessionName=$this;
			//var_dump(Session::getInstance()->__frodoSessionName);
			echo "saving application=".Session::getInstance()->__frodoSessionName->getInternalCode();
			Session::commit();
		}
	}
	
	public static function run($appName,$filePath){
		$newApp= new $appName();
		$newApp->setName($appName);
		$newApp->setInternalCode(md5(rand(0,9999999)));
		$oldApp=Session::getInstance()->__frodoSessionName;
		if(!method_exists($oldApp,"getInternalCode")||(@$_POST["__INTERNALCODE_"]!=$oldApp->getInternalCode())){
			$app=$newApp;
			Session::getInstance()->__frodoSessionName->expired=true;
		}else{
			$newApp->expired=true;
			$app=$oldApp;
		}
		$app->setPath($filePath);
		$app->create();
		if(method_exists($app,"main")&&$newApp->expired==false)$app->main();
		$app->dispatchEvents();
		//$app->create();
		echo $app->getHtml();
		exit();
	}
}

?>